/**
 * Copyright (c) 2003 held jointly by the individual authors.            
 *                                                                          
 * This library is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU Lesser General Public License as published      
 * by the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.                                            
 *                                                                            
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; with out even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * GNU Lesser General Public License for more details.                                                  
 *                                                                           
 * You should have received a copy of the GNU Lesser General Public License   
 * along with this library;  if not, write to the Free Software Foundation,   
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.              
 *                                                                            
 * > http://www.gnu.org/copyleft/lesser.html                                  
 * > http://www.opensource.org/licenses/lgpl-license.php
 */

package cn.duhengkui.national.valuelist.core.data.util;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Map;
import java.util.StringTokenizer;


/**   
 * <table border="1">
 *	<tr><td>包名称：</td><td>cn.duhengkui.national.valuelist.core.data.util</td></tr>
 *	<tr><td>类名称：</td><td>FilterTextManipulator</td></tr>
 *	<tr><td>类描述：</td><td>sql处理不固定条件</td></tr>
 *	<tr><td>创建人：</td><td>杜恒奎</td></tr>
 *  <tr><td>创建时间：</td><td>2018年6月7日/下午3:04:35</td></tr> 
 *  <tr><td>版本：</td><td>1.0.0</td></tr>
 * </table>   
 *     
 */
public class FilterTextManipulator implements TextManipulator {

	private String	startToken	= "/~";

	private String	endToken		= "~/";


	
	/* (non-Javadoc)
	 * @see cn.duhengkui.national.valuelist.core.data.util.TextManipulator#manipulate(java.lang.StringBuilder, java.util.Map)
	 */
	public StringBuilder manipulate(StringBuilder text, Map<String, Object> model) {
		if (model == null) {
			model = Collections.emptyMap();
		}
		boolean inverse = false;
		for (int start = 0, end = text.indexOf(endToken); ((end = text.indexOf(endToken)) >= 0);) {
			start = text.lastIndexOf(startToken, end);
			String key = text.substring(start + 2, text.indexOf(":", start));
			// If this is an or statement
			if (key.indexOf(',') != -1) {
				for (StringTokenizer st = new StringTokenizer(key, ","); st.hasMoreElements();) {
					Object modelValue = model.get((key = st.nextToken()));
					if (modelValue instanceof String && (((String) modelValue).length() == 0)) {
						continue;
					} else if (modelValue != null) {
						break;
					}
				}
			} else if (key.indexOf('|') != -1) {
				for (StringTokenizer st = new StringTokenizer(key, "|"); st.hasMoreElements();) {
					Object modelValue = model.get((key = st.nextToken()));
					if (modelValue instanceof String && (((String) modelValue).length() == 0)) {
						continue;
					} else if (modelValue != null) {
						break;
					}
				}
			} else if (key.indexOf('&') != -1) {
				for (StringTokenizer st = new StringTokenizer(key, "&"); st.hasMoreElements();) {
					Object modelValue = model.get((key = st.nextToken()));
					if (modelValue == null || modelValue instanceof String && (((String) modelValue).length() == 0)) {
						break;
					}
				}
			}
			if ((inverse = key.startsWith("!"))) {
				key = key.substring(1, key.length());
			}
			Object modelValue = null;
			try {
				modelValue = ReflectUtil.getValue(model, key);
			} catch (NoSuchMethodException | SecurityException
					| IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
			}
			// If its an empty string replace it with a null.
			if (modelValue instanceof String && (((String) modelValue).length() == 0)) {
				modelValue = null;
			}
			if (inverse) {
				if ((modelValue == null)) {
					text.replace(start, end + 2, text.substring(text.indexOf(":", start) + 1, end));
				} else {
					text.replace(start, end + 2, "");
				}
			} else {
				if ((modelValue != null)) {
					text.replace(start, end + 2, text.substring(text.indexOf(":", start) + 1, end));
				} else {
					text.replace(start, end + 2, "");
				}
			}
		}
		return text;
	}

	/**
	 * @param endToken The endToken to set.
	 */
	public void setEndToken(String endToken) {
		this.endToken = endToken;
	}

	/**
	 * @param startToken The startToken to set.
	 */
	public void setStartToken(String startToken) {
		this.startToken = startToken;
	}
}